#include "dnfs.h"
#include "common.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <math.h>
#include <sys/resource.h>
//#define _XOPEN_SOURCE 500
#include <unistd.h>
char OSDROOT[NAMELEN];

//返回写成功的Bytes数或者-errno
bool_t co_write_2_svc(struct co_write_in *arg, int *res, struct svc_req *rqst)
{
	
	int 	size 	= arg->buf.buf_len;
	char 	*buf 	= arg->buf.buf_val;
	char 	*oid 	= arg->oid;
	off_t 	offset 	= arg->offset;
	int 	fd;
	char	path[NAMELEN];
PDEBUG("[co_write] oid = %s, size = %d, offset = %ld\t", oid, size, offset);
	sprintf(path, "%s/%s", OSDROOT, oid);
	fd = open(path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);//如果不存在，则新建
    	if (fd == -1) {
		*res  = -errno;
		printf("open %s failed, res = %d: %s\n", path, -*res, strerror(-*res));
		return TRUE;
	}
        
    	*res = pwrite(fd, buf, size, offset);
    	if (*res == -1)
        	*res = -errno;//负数

    	close(fd);
PDEBUG("res = %d\n", *res);
	return TRUE;	
}

bool_t co_read_2_svc(struct co_read_in *arg, struct co_read_out *res, struct svc_req *rqst)
{
	int 	size 	= arg->size;
	char 	*oid 	= arg->oid;//(char *) malloc (OIDLEN);
	off_t 	offset 	= arg->offset;
	int 	fd;
	char	path[NAMELEN];

PDEBUG("[co_read] oid = %s, size = %d, offset = %ld\t", oid, size, offset);

	char 	*buf 	= (char *) malloc (size);
	res->buf.buf_val = buf;

	sprintf(path, "%s/%s", OSDROOT, oid);
	fd = open(path, O_RDONLY);//如果不存在，则新建
    	if (fd == -1) {
		res->res  = -errno;
		res->buf.buf_len = 0;
		printf("open %s failed, res = %d: %s\n", path, errno, strerror(errno));
		return TRUE;
	}
        
    	res->res = pread(fd, buf, size, offset);
    	if (res->res == -1) {
        	res->res = -errno;//负数
		res->buf.buf_len = 0;
	}
	else {
		res->buf.buf_len = res->res;
	}

    	close(fd);
PDEBUG("res = %d\n", res->res);
	return TRUE;
}

bool_t so_truncate_2_svc(struct so_truncate_in *arg, int *res, struct svc_req *rqst)
{
	return TRUE;
}

bool_t so_unlink_2_svc(struct so_unlink_in *arg, int *res, struct svc_req *rqst)
{
	char	path[NAMELEN];
	sprintf(path, "%s/%s", OSDROOT, arg->oid);
PDEBUG("[so_unlink] : %s\t", path);
	
	*res = unlink(path);
    	if (*res == -1)
        	 *res = -errno;
PDEBUG("res = %d\n", *res);

	return TRUE;
}


int so_2_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
{
	xdr_free(xdr_result, result);
	return 1;
}

int co_2_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
{
	xdr_free(xdr_result, result);
	return 1;
}
